package com.scheduling.machine.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scheduling.common.constants.CommonConstants;
import com.scheduling.machine.dto.MachineDTO;
import com.scheduling.machine.dto.MachineQueryDTO;
import com.scheduling.machine.entity.Machine;
import com.scheduling.machine.mapper.MachineMapper;
import com.scheduling.machine.mapper.MachineTypeMapper;
import com.scheduling.machine.service.MachineService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 机器业务层实现类
 *
 * @author 开发团队
 * @since 2025-05-29
 */
@Slf4j
@Service
public class MachineServiceImpl extends ServiceImpl<MachineMapper, Machine> implements MachineService {

    @Autowired
    private MachineTypeMapper machineTypeMapper;

    @Override
    public IPage<Machine> getMachinePage(MachineQueryDTO queryDTO) {
        Page<Machine> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        return baseMapper.selectMachinePageWithType(page, queryDTO);
    }

    @Override
    public Machine getMachineById(String machineId) {
        if (StrUtil.isBlank(machineId)) {
            throw new RuntimeException("机器ID不能为空");
        }
        return baseMapper.selectById(machineId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addMachine(MachineDTO machineDTO) {
        // 检查机器名称是否已存在
        if (checkMachineNameExists(machineDTO.getMachineName(), null)) {
            throw new RuntimeException("机器名称已存在");
        }

        // 检查机器类型是否存在
        if (machineTypeMapper.selectById(machineDTO.getMachineTypeId()) == null) {
            throw new RuntimeException("机器类型不存在");
        }

        // 生成机器ID
        if (machineDTO.getMachineId() == null || machineDTO.getMachineId().isEmpty()) {
            Integer maxId = baseMapper.selectMaxMachineNumber();
            int nextNum = (maxId != null) ? maxId + 1 : 1;
            String newId = String.format("MAC%04d", nextNum);
            machineDTO.setMachineId(newId);
        }

        Machine machine = new Machine();
        BeanUtil.copyProperties(machineDTO, machine);

        // 设置默认状态为空闲
        if (StrUtil.isBlank(machine.getStatus())) {
            machine.setStatus(CommonConstants.MACHINE_STATUS_IDLE);
        }
        int result = baseMapper.insert(machine);
        if (result > 0) {
            log.info("添加机器成功，机器ID：{}", machine.getMachineId());
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateMachine(MachineDTO machineDTO) {
        if (StrUtil.isBlank(machineDTO.getMachineId())) {
            throw new RuntimeException("机器ID不能为空");
        }

        // 检查机器是否存在
        Machine existMachine = baseMapper.selectById(machineDTO.getMachineId());
        if (existMachine == null) {
            throw new RuntimeException("机器不存在");
        }

        // 检查机器名称是否已存在（排除当前机器）
        if (checkMachineNameExists(machineDTO.getMachineName(), machineDTO.getMachineId())) {
            throw new RuntimeException("机器名称已存在");
        }

        // 检查机器类型是否存在
        if (machineTypeMapper.selectById(machineDTO.getMachineTypeId()) == null) {
            throw new RuntimeException("机器类型不存在");
        }

        Machine machine = new Machine();
        BeanUtil.copyProperties(machineDTO, machine);

        int result = baseMapper.updateById(machine);
        if (result > 0) {
            log.info("更新机器成功，机器ID：{}", machine.getMachineId());
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteMachine(String machineId) {
        if (StrUtil.isBlank(machineId)) {
            throw new RuntimeException("机器ID不能为空");
        }

        // 检查机器是否存在
        Machine machine = baseMapper.selectById(machineId);
        if (machine == null) {
            throw new RuntimeException("机器不存在");
        }

        // 检查机器是否被生产任务引用
        Integer taskCount = baseMapper.countProductionTasksByMachineId(machineId);
        if (taskCount != null && taskCount > 0) {
            throw new RuntimeException("该机器有关联的生产任务，无法删除。请先处理相关任务。");
        }

        // 检查机器状态，如果正在生产中则不能删除
        if ("生产中".equals(machine.getStatus())) {
            throw new RuntimeException("机器正在生产中，无法删除");
        }

        int result = baseMapper.deleteById(machineId);
        if (result > 0) {
            log.info("删除机器成功，机器ID：{}", machineId);
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteMachines(List<String> machineIds) {
        if (machineIds == null || machineIds.isEmpty()) {
            throw new RuntimeException("机器ID列表不能为空");
        }

        for (String machineId : machineIds) {
            deleteMachine(machineId);
        }
        return true;
    }

    @Override
    public List<Machine> getMachinesByTypeId(String machineTypeId) {
        if (StrUtil.isBlank(machineTypeId)) {
            throw new RuntimeException("机器类型ID不能为空");
        }

        LambdaQueryWrapper<Machine> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Machine::getMachineTypeId, machineTypeId);
        wrapper.orderByAsc(Machine::getMachineName);
        return baseMapper.selectList(wrapper);
    }

    public List<Machine> getIdleMachines() {
        // 使用新的mapper方法查询空闲机器
        return baseMapper.selectIdleMachinesWithType("空闲");
    }

    @Override
    public boolean checkMachineNameExists(String machineName, String excludeId) {
        if (StrUtil.isBlank(machineName)) {
            return false;
        }
        Integer count = baseMapper.checkMachineNameExists(machineName, excludeId);
        return count != null && count > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateMachineStatus(String machineId, String status) {
        if (StrUtil.isBlank(machineId)) {
            throw new RuntimeException("机器ID不能为空");
        }
        if (StrUtil.isBlank(status)) {
            throw new RuntimeException("机器状态不能为空");
        }

        Machine machine = baseMapper.selectById(machineId);
        if (machine == null) {
            throw new RuntimeException("机器不存在");
        }

        machine.setStatus(status);
        int result = baseMapper.updateById(machine);
        if (result > 0) {
            log.info("更新机器状态成功，机器ID：{}，新状态：{}", machineId, status);
            return true;
        }
        return false;
    }
}